WOLF core
WOLF: A Modular Estimation Framework for Robotics
XXXXXXXXXXXXXXXXXXXXXXXXvoid(0)" frameborder="0" name="MSearchResults" id="MSearchResults">
utils_gtest.h
Go to the documentation of this file.
1// WOLF - Copyright (C) 2020-2026
2// Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
3// Authors: Joan Solà Ortega (jsola@iri.upc.edu) and
4// Joan Vallvé Navarro (jvallve@iri.upc.edu)
5// All rights reserved.
6//
7// This file is part of WOLF: http://www.iri.upc.edu/wolf
8// WOLF is free software: you can redistribute it and/or modify
9// it under the terms of the GNU General Public License version 3
10// as published by the Free Software Foundation.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program. If not, see <http://www.gnu.org/licenses/>.
19#pragma once
20
21#include <gtest/gtest.h>
22#include <Eigen/Dense>
23
24// Macros for testing equalities and inequalities.
25//
26// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
27// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2
28// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2
29// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2
30// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2
31// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2
32//
33// C String Comparisons. All tests treat NULL and any non-NULL string
34// as different. Two NULLs are equal.
35//
36// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2
37// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2
38// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case
39// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case
40//
41// Macros for comparing floating-point numbers.
42//
43// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual):
44// Tests that two float values are almost equal.
45// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual):
46// Tests that two double values are almost equal.
47// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error):
48// Tests that v1 and v2 are within the given distance to each other.
49//
50// These predicate format functions work on floating-point values, and
51// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g.
52//
53// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0);
54//
55// Macros that execute statement and check that it doesn't generate new fatal
56// failures in the current thread.
57//
58// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement);
59
66{
67 // gtest/CMakeLists.txt defines this environment variable when launching tests
68 return std::getenv("DASHBOARD_TEST_FROM_CTEST") != NULL;
69}
70
71namespace testing
72{
73/* Macros related to testing Eigen classes:
74 */
75#define EXPECT_MATRIX_APPROX(C_expect, C_actual, precision) \
76 EXPECT_PRED2([](const Eigen::MatrixXd& lhs, \
77 const Eigen::MatrixXd& rhs) { return (lhs - rhs).isMuchSmallerThan(1, precision); }, \
78 C_expect, \
79 C_actual);
80
81#define ASSERT_MATRIX_APPROX(C_expect, C_actual, precision) \
82 ASSERT_PRED2([](const Eigen::MatrixXd& lhs, \
83 const Eigen::MatrixXd& rhs) { return (lhs - rhs).isMuchSmallerThan(1, precision); }, \
84 C_expect, \
85 C_actual);
86
87#define EXPECT_QUATERNION_APPROX(C_expect, C_actual, precision) \
88 EXPECT_PRED2([](const Eigen::Quaterniond& lhs, \
89 const Eigen::Quaterniond& rhs) { return lhs.angularDistance(rhs) < precision; }, \
90 C_expect, \
91 C_actual);
92
93#define ASSERT_QUATERNION_APPROX(C_expect, C_actual, precision) \
94 ASSERT_PRED2([](const Eigen::Quaterniond& lhs, \
95 const Eigen::Quaterniond& rhs) { return lhs.angularDistance(rhs) < precision; }, \
96 C_expect, \
97 C_actual);
98
99#define EXPECT_QUATERNION_VECTOR_APPROX(C_expect, C_actual, precision) \
100 EXPECT_PRED2( \
101 [](const Eigen::VectorXd& lhs, const Eigen::VectorXd& rhs) { \
102 return Eigen::Quaterniond(Eigen::Vector4d(lhs)) \
103 .angularDistance(Eigen::Quaterniond(Eigen::Vector4d(rhs))) < precision; \
104 }, \
105 C_expect, \
106 C_actual);
107
108#define ASSERT_QUATERNION_VECTOR_APPROX(C_expect, C_actual, precision) \
109 ASSERT_PRED2( \
110 [](const Eigen::VectorXd& lhs, const Eigen::VectorXd& rhs) { \
111 return Eigen::Quaterniond(Eigen::Vector4d(lhs)) \
112 .angularDistance(Eigen::Quaterniond(Eigen::Vector4d(rhs))) < precision; \
113 }, \
114 C_expect, \
115 C_actual);
116
117#define EXPECT_POSE2d_APPROX(C_expect, C_actual, precision) \
118 EXPECT_PRED2( \
119 [](const Eigen::VectorXd& lhs, const Eigen::VectorXd& rhs) { \
120 assert(lhs.size() == 3 and rhs.size() == 3); \
121 Eigen::VectorXd er = lhs - rhs; \
122 er(2) = remainder((double)er(2), 2 * M_PI); \
123 return er.isMuchSmallerThan(1, precision); \
124 }, \
125 C_expect, \
126 C_actual);
127
128#define ASSERT_POSE2d_APPROX(C_expect, C_actual, precision) \
129 ASSERT_PRED2( \
130 [](const Eigen::VectorXd& lhs, const Eigen::VectorXd& rhs) { \
131 assert(lhs.size() == 3 and rhs.size() == 3); \
132 Eigen::VectorXd er = lhs - rhs; \
133 er(2) = remainder((double)er(2), 2 * M_PI); \
134 return er.isMuchSmallerThan(1, precision); \
135 }, \
136 C_expect, \
137 C_actual);
138
139#define EXPECT_POSE3d_APPROX(C_expect, C_actual, precision) \
140 EXPECT_PRED2( \
141 [](const Eigen::VectorXd& lhs, const Eigen::VectorXd& rhs) { \
142 assert(lhs.size() == 7 and rhs.size() == 7); \
143 Eigen::Vector4d er; \
144 er.head(3) = lhs.head(3) - rhs.head(3); \
145 er(3) = Eigen::Quaterniond(Eigen::Vector4d(lhs.tail(4))) \
146 .angularDistance(Eigen::Quaterniond(Eigen::Vector4d(rhs.tail(4)))); \
147 return er.isMuchSmallerThan(1, precision); \
148 }, \
149 C_expect, \
150 C_actual);
151
152#define ASSERT_POSE3d_APPROX(C_expect, C_actual, precision) \
153 ASSERT_PRED2( \
154 [](const Eigen::VectorXd& lhs, const Eigen::VectorXd& rhs) { \
155 assert(lhs.size() == 7 and rhs.size() == 7); \
156 Eigen::Vector4d er; \
157 er.head(3) = lhs.head(3) - rhs.head(3); \
158 er(3) = Eigen::Quaterniond(Eigen::Vector4d(lhs.tail(4))) \
159 .angularDistance(Eigen::Quaterniond(Eigen::Vector4d(rhs.tail(4)))); \
160 return er.isMuchSmallerThan(1, precision); \
161 }, \
162 C_expect, \
163 C_actual);
164
165} // namespace testing
Definition: utils_gtest.h:72
bool is_running_under_ctest()
Checks if the code is running under CTest Useful to avoid launching visualizers and other interactive...
Definition: utils_gtest.h:65